#include "adc_app.h"

osThreadId_t adc_TaskHandle;
const osThreadAttr_t adc_Task_attributes = {
  .name = "adc_Task",
  .stack_size = ADC_TASK_STACK_SIZE * 4,
  .priority = (osPriority_t) ADC_STORAGE_TASK_PRIORITY,
};

static void adc_data_proc(uint32_t *adc_rx_data, float *adc_data_f) {
    // Initialize result array
    for (uint8_t i = 0; i < 16; i++) {
        adc_data_f[i] = 0.0f;
    }

    // Process ADC data for 16 channels
    for (uint8_t ch = 0; ch < 16; ch++) {            // ch: channel number (0~15)
        uint32_t samples[10];                        // Store 10 samples for current channel

        // 1. Extract 10 sample data points for current channel
        for (uint8_t n = 0; n < 10; n++) {           // n: sample count (0~9)
            samples[n] = adc_rx_data[ch + n * 16];   // Data format: [ch0_sample0, ch1_sample0,...ch15_sample0, ch0_sample1,...]
        }

        // 2. Sort samples (bubble sort, ascending) for outlier removal
        for (uint8_t i = 0; i < 9; i++) {            // 9 passes needed for 10 elements
            for (uint8_t j = 0; j < 9 - i; j++) {
                if (samples[j] > samples[j + 1]) {
                    // Swap elements
                    uint32_t temp = samples[j];
                    samples[j] = samples[j + 1];
                    samples[j + 1] = temp;
                }
            }
        }

        // 3. Pulse interference filtering: remove 1 min and 1 max value, average middle 8 values
        uint32_t sum = 0;
        for (uint8_t k = 1; k < 9; k++) {         // Take indices 1~8 (8 values total)
            sum += samples[k];
        }
        float avg_raw = (float)sum / 8.0f;        // Filtered raw ADC average

        // 4. Convert to voltage (assuming 12-bit ADC, 3.3V reference: voltage = average / 4096 * 3.3)
        float voltage = avg_raw / 4096.0f * 3.3f;

        // 5. Keep two decimal places (round to ensure zeros after second decimal)
        voltage = (float)((int)(voltage * 100.0f + 0.5f)) / 100.0f;

        // Assign to result array
        adc_data_f[ch] = voltage;
    }
}

void adc_Task(void *argument)
{
  /* USER CODE BEGIN StartDefaultTask */
  /* Infinite loop */
	uint32_t adc_rx_data[160];
	float adc_data_f[16];
	HAL_ADC_Start_DMA(&hadc1, adc_rx_data, 160);
  for(;;)
  {

		adc_data_proc(adc_rx_data, adc_data_f);
		
    #ifdef DBUG
      for(uint8_t i=0;i<16;i++){
        printf("%.2f ", adc_data_f[i]);
      }
      printf("\n");
    #endif
		
		if(xQueueSend(xQueue_Uart, adc_data_f, pdMS_TO_TICKS(100)) != pdPASS){
     #ifdef DBUG
				printf("\nxQueue_Uart_xQueueSend_err\n");
			#endif
		}
		
    osDelay(ADC_Collection_TIME);
  }
  /* USER CODE END StartDefaultTask */
}
